package cn.tuling.example;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * 五子棋
 */
public class FlyWeightTest {
    public static void main(String[] args) {
        ChessPieceFactory factory = new ChessPieceFactory();
        factory.getChessPiece(Color.WHITE).DownPiece(new Point(0, 1));
        factory.getChessPiece(Color.BLACK).DownPiece(new Point(2, 2));
        factory.getChessPiece(Color.WHITE).DownPiece(new Point(1, 1));
    }
}

/**
 * 落子位置是变化的
 */
class Point {
    private int x;
    private int y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }
}

/**
 * 享元角色：为保证线程安全，有两种方式：
 * 1. 创建为不可变对象（常用）
 * 2. 数据一致性，加锁
 */
interface ChessPiece {
    void DownPiece(Point point);
}

class WhitePiece implements ChessPiece {
    // 测试用, 无意义
    private final String name;

    public WhitePiece(String name) {
        this.name = name;
    }

    @Override
    public void DownPiece(Point point) {
        System.out.println(name + "落在(" + point.getX() + "," + point.getY() + ")位置");
    }
}

class BlackPiece implements ChessPiece {
    private final String name;

    public BlackPiece(String name) {
        this.name = name;
    }

    @Override
    public void DownPiece(Point point) {
        System.out.println(name + "落在(" + point.getX() + "," + point.getY() + ")位置");
    }
}

enum Color {
    WHITE, BLACK;
}

class ChessPieceFactory {
    /**
     * 为保证数据安全，使用JUC下面的List
     */
    private static List<ChessPiece> chessPieces;

    public ChessPieceFactory() {
        this.chessPieces = new CopyOnWriteArrayList<>();
        chessPieces.add(new WhitePiece("白子1"));
        chessPieces.add(new BlackPiece("黑子1"));
    }

    public ChessPiece getChessPiece(Color color) {
        if (color.equals(Color.WHITE)) {
            return chessPieces.get(0);
        } else if (color.equals(Color.BLACK)) {
            return chessPieces.get(1);
        } else {
            return null;
        }
    }
}


